########## Afrobarometer (main text) #############

## This code replicates all analyses using Afrobarometer survey data presented in the main text ##

## Load required packages

rm(list=ls())

library(tidyverse)
library(fixest)

#### Load AB data

AB_malawi <- readRDS("AB_malawi.rds")

####### FIGURE 3 (Mobile coverage and ind. access to the internet) ########

## Run specifications

AB1.1 <- feols(smartphone_bin*100 ~ i(group, ref="Control")  + 
                 i(partisanship, ref = "Independent") + 
                 age + male + education + urbrur + i(ethnicity) +
                 hh_basket | district,
               data=AB_malawi, 
               cluster=~ea_code)

AB1.2 <- feols(socmedia_news_bin*100 ~ i(group, ref="Control")  + 
                 i(partisanship, ref = "Independent") + 
                 age + male + education + urbrur + i(ethnicity) +
                 hh_basket | district,
               data=AB_malawi, 
               cluster=~ea_code)

AB1.3 <- feols(internet_news_bin*100 ~ i(group, ref="Control")  + 
                 i(partisanship, ref = "Independent") + 
                 age + male + education + urbrur + i(ethnicity) +
                 hh_basket | district,
               data=AB_malawi, 
               cluster=~ea_code)

AB1.4 <- feols(socmedia_heard*100 ~ i(group, ref="Control")  + 
                 i(partisanship, ref = "Independent") + 
                 age + male + education + urbrur + i(ethnicity) +
                 hh_basket | district,
               data=AB_malawi, 
               cluster=~ea_code)

## Save results into data.frame
AB_list_socmedia <- list(AB1.1, AB1.2, AB1.3, AB1.4)

## With 95% CIs
AB_df_socmedia <- map_df(AB_list_socmedia, broom::tidy, .id="model") %>%
  filter(term == "group::Enter coverage") %>%
  mutate(conf.low95 = estimate - 1.96*std.error,
         conf.high95 = estimate + 1.96*std.error,
         conf.low90 = estimate - 1.68*std.error,
         conf.high90 = estimate + 1.68*std.error,
         outcome = rep(c("Own\nsmartphone", 
                         "Social media news\n(At least monthly)", 
                         "Internet news\n(At least monthly)",
                         "Heard of social media\nplatforms")))

## Make plot

ggplot(data=AB_df_socmedia, aes(x = estimate, 
                                         y = factor(outcome, 
                                                    levels = c("Own\nsmartphone", 
                                                               "Heard of social media\nplatforms",
                                                               "Social media news\n(At least monthly)", 
                                                               "Internet news\n(At least monthly)")))) +
  theme(panel.border = element_rect(colour = "black", fill = NA)) +
  geom_vline(xintercept=0, linetype=2) +
  geom_errorbarh(aes(xmin=conf.low90, xmax=conf.high90, height=0, width=0), size=0.7,
                 position = position_dodge(width=0.3), col="darkblue") +
  geom_errorbarh(aes(xmin=conf.low95, xmax=conf.high95, height=0, width=0), alpha=0.7,
                 position = position_dodge(width=0.3), col="darkblue") +
  geom_point(position = position_dodge(width=0.3), col="darkblue") +
  theme_bw() +
  scale_x_continuous(limits = c(-1, 22), 
                     breaks = c(0, 5, 10, 15, 20), 
                     labels = c("0%", "5%", "10%", "15%", "20%")) +
  theme(legend.position = "bottom",
        legend.title = element_blank(),
        axis.title.x = element_blank()) +
  coord_flip() +
  scale_colour_manual(values = c("darkblue")) +
  xlab("% Difference\n(Newly covered vs outside)") 


###### FIGURE 6 (party contact and incumbent support) ########

## Make new dataset for "among contacted" models, subsetting for respondents any contact
## Other models use same full dataset as before

ABcontact <- AB_malawi %>% 
  filter(election_contact == "1") %>%
  mutate(contact_dpp = ifelse(is.na(contact_dpp) == "TRUE", 0, contact_dpp),
         contact_mcp = ifelse(is.na(contact_mcp) == "TRUE", 0, contact_mcp))

### Qs about contact in election (for mechanisms)

AB2.1 <- feols(contact_dpp*100 ~ i(group, ref="Control")  + 
                 i(partisanship, ref = "Independent") + 
                 age + male + education + urbrur + i(ethnicity) +
                 hh_basket | district,
               data=AB_malawi, 
               cluster=~ea_code)

AB2.2 <- feols(contact_mcp*100 ~ i(group, ref="Control")  + 
                 i(partisanship, ref = "Independent") + 
                 age + male + education + urbrur + i(ethnicity) +
                 hh_basket | district,
               data=AB_malawi, 
               cluster=~ea_code)

AB2.3 <- feols(contact_dpp*100 ~ i(group, ref="Control") + 
                 i(partisanship, ref = "Independent") + 
                 age + male + education + urbrur + i(ethnicity) +
                 hh_basket | district,
               data=ABcontact, 
               cluster=~ea_code) ## Note: uses "among contacted" dataset

AB2.4 <- feols(contact_mcp*100 ~ i(group, ref="Control")  + 
                 i(partisanship, ref = "Independent") + 
                 age + male + education + urbrur + i(ethnicity) +
                 hh_basket | district,
               data=ABcontact, 
               cluster=~ea_code) ## Note: uses "among contacted" dataset

AB2.5 <- feols(trust_ruling_std*100 ~ i(group, ref="Control")  + 
                 i(partisanship, ref = "Independent") + 
                 age + male + education + urbrur + i(ethnicity) +
                 hh_basket | district,
               data=AB_malawi, 
               cluster=~ea_code)

AB2.6 <- feols(performance_pres_std*100 ~ i(group, ref="Control")  + 
                 i(partisanship, ref = "Independent") + 
                 age + male + education + urbrur + i(ethnicity) +
                 hh_basket | district,
               data=AB_malawi, 
               cluster=~ea_code)


## Save results as data.frame

AB_list_contact <- list(AB2.1, AB2.2, AB2.3, AB2.4, AB2.5, AB2.6)
AB_df_contact <- map_df(AB_list_contact, broom::tidy, .id="model") %>%
  filter(term == "group::Enter coverage") %>%
  mutate(conf.low95 = estimate - 1.96*std.error,
         conf.high95 = estimate + 1.96*std.error,
         conf.low90 = estimate - 1.68*std.error,
         conf.high90 = estimate + 1.68*std.error,
         outcome = rep(c("DPP (vs no contact)", 
                         "MCP (vs no contact)", 
                         "DPP (among contacted)", 
                         "MCP (among contacted)", 
                         "Trust ruling", "Pres performance")), 
         subtype = ifelse(outcome == "DPP (among contacted)" |
                            outcome == "MCP (among contacted)", 
                          "Contact\n(among contacted)", 
                          ifelse(outcome == "DPP (vs no contact)" |
                                   outcome == "MCP (vs no contact)",
                                 "Contact\n(vs no contact)", "Incumbent support\n(standardised)")),
         outcome = ifelse(outcome == "DPP (among contacted)", "DPP",
                          ifelse(outcome == "MCP (among contacted)", "MCP",
                                 ifelse(outcome == "DPP (vs no contact)", "DPP",
                                        ifelse(outcome == "MCP (vs no contact)", "MCP", outcome)))))

### Make plot

ggplot(data=AB_df_contact, aes(x = estimate, 
                              y = outcome)) +
  theme(panel.border = element_rect(colour = "black", fill = NA)) +
  facet_wrap(~factor(subtype),
             scales="free") +
  geom_vline(xintercept=0, linetype=2) +
  geom_errorbarh(aes(xmin=conf.low90, xmax=conf.high90, height=0, width=0), size=0.7,
                 position = position_dodge(width=0.3), col="darkblue") +
  geom_errorbarh(aes(xmin=conf.low95, xmax=conf.high95, height=0, width=0), alpha=0.7,
                 position = position_dodge(width=0.3), col="darkblue") +
  geom_point(position = position_dodge(width=0.3), col="darkblue") +
  theme_bw() +
  theme(legend.position = "bottom",
        legend.title = element_blank(),
        axis.title.x = element_blank()) +
  coord_flip() +
  scale_colour_manual(values = c("darkblue")) +
  xlab("% Difference\n(Newly covered vs outside)") 



